import datetime
import logging

import requests

from redash.query_runner import *
from redash.utils import json_dumps

logger = logging.getLogger(__name__)


def _transform_result(response):
    columns = ({'name': 'Time::x', 'type': TYPE_DATETIME},
               {'name': 'value::y', 'type': TYPE_FLOAT},
               {'name': 'name::series', 'type': TYPE_STRING})

    rows = []

    for series in response.json():
        for values in series['datapoints']:
            timestamp = datetime.datetime.fromtimestamp(int(values[1]))
            rows.append({'Time::x': timestamp, 'name::series': series['target'], 'value::y': values[0]})

    data = {'columns': columns, 'rows': rows}
    return json_dumps(data)


class Graphite(BaseQueryRunner):
    should_annotate_query = False

    @classmethod
    def configuration_schema(cls):
        return {
            'type': 'object',
            'properties': {
                'url': {
                    'type': 'string'
                },
                'username': {
                    'type': 'string'
                },
                'password': {
                    'type': 'string'
                },
                'verify': {
                    'type': 'boolean',
                    'title': 'Verify SSL certificate'
                }
            },
            'required': ['url'],
            'secret': ['password']
        }

    def __init__(self, configuration):
        super(Graphite, self).__init__(configuration)
        self.syntax = 'custom'

        if "username" in self.configuration and self.configuration["username"]:
            self.auth = (self.configuration["username"], self.configuration["password"])
        else:
            self.auth = None

        self.verify = self.configuration.get("verify", True)
        self.base_url = "%s/render?format=json&" % self.configuration['url']

    def test_connection(self):
        r = requests.get("{}/render".format(self.configuration['url']), auth=self.auth, verify=self.verify)
        if r.status_code != 200:
            raise Exception("Got invalid response from Graphite (http status code: {0}).".format(r.status_code))

    def run_query(self, query, user):
        url = "%s%s" % (self.base_url, "&".join(query.split("\n")))
        error = None
        data = None

        try:
            response = requests.get(url, auth=self.auth, verify=self.verify)

            if response.status_code == 200:
                data = _transform_result(response)
            else:
                error = "Failed getting results (%d)" % response.status_code
        except Exception as ex:
            data = None
            error = ex.message

        return data, error


register(Graphite)
